import type { AppContext, DatabaseType } from '../types/index.js';
import { ServerException } from '../types/exceptions.js';
import { Pool as MySQLPool } from 'mysql2/promise';
import { Pool as PgPool } from 'pg';

interface KoaApp {
  currentContext: AppContext | null;
}

/**
 * 全局上下文工具类
 * 基于 Koa 3 的 asyncLocalStorage 功能，提供不需要显式传递 ctx 的上下文访问
 */
export class GlobalContext {
  private static app: KoaApp;

  /**
   * 初始化全局上下文，需要在应用启动时调用
   * @param koaApp Koa 应用实例
   */
  static init(koaApp: KoaApp): void {
    GlobalContext.app = koaApp;
  }

  /**
   * 获取当前请求的上下文
   * @returns 当前请求的 AppContext 实例
   * @throws Error 如果没有当前上下文或未初始化
   */
  static getCurrentContext(): AppContext {
    if (!GlobalContext.app) {
      throw new ServerException('GlobalContext 未初始化，请先调用 GlobalContext.init(app)');
    }

    const ctx = GlobalContext.app.currentContext;
    if (!ctx) {
      throw new ServerException('无法获取当前上下文，请确保在请求处理过程中调用此方法');
    }

    return ctx as AppContext;
  }

  /**
   * 安全获取当前请求的上下文
   * @returns 当前请求的 AppContext 实例或 null
   */
  static tryGetCurrentContext(): AppContext | null {
    try {
      return GlobalContext.getCurrentContext();
    } catch {
      return null;
    }
  }

  /**
   * 获取当前请求的数据库连接池
   * @returns 当前请求的数据库连接池实例
   * @throws Error 如果没有当前上下文或未初始化
   */
  static getDbPool(): MySQLPool | PgPool {
    return GlobalContext.getCurrentContext().getDbPool();
  }

  /**
   * 获取当前请求的数据库类型
   * @returns 当前请求的数据库类型
   * @throws Error 如果没有当前上下文或未初始化
   */
  static getDbType(): DatabaseType {
    return GlobalContext.getCurrentContext().dbType;
  }
}
